package org.artifact.core.plugin.rmi;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import org.artifact.core.lang.AbstractPlugin;

import java.rmi.Remote;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RMISocketFactory;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

public class RmiPlugin extends AbstractPlugin {

	static Log log = LogFactory.get(RmiPlugin.class);

	private String host;
	private int clientSocketPort;
	private int serverSocketPort;

	private Registry registry = null;

	private Map<String, Remote> remotes = new HashMap<>();

	public RmiPlugin(String host, int clientSocketPort, int serverSocketPort) {
		super();
		this.host = host;
		this.clientSocketPort = clientSocketPort;
		this.serverSocketPort = serverSocketPort;
	}

	@Override
	public boolean start() {
		try {
			// 指定通信端口
			RMISocketFactory.setSocketFactory(new SMRMISocket(serverSocketPort));

			// 指定服务器端口
			System.setProperty("java.rmi.server.hostname", host);

			registry = LocateRegistry.createRegistry(clientSocketPort);

			// 将远程对象实例绑定到rmi:///Rem上
			for (Entry<String, Remote> e : remotes.entrySet()) {
				registry.rebind(e.getKey(), e.getValue());
				log.debug("rmi bind //{}:{}/{} -> {}", host, clientSocketPort, e.getKey(),
						e.getValue().getClass().getName());
			}
		} catch (Exception e) {
			log.error(e);
			return false;
		}

		return true;
	}

	@Override
	public boolean stop() {
		try {
			for (Entry<String, Remote> e : remotes.entrySet()) {
				registry.unbind(e.getKey());
			}
			UnicastRemoteObject.unexportObject(registry, true);
		} catch (Exception e) {
			log.error(e);
			return false;
		}
		return true;
	}

}
